<template>
  <li class="v-side-submenu"
    :class="{
      'is-active': active,
      'is-opened': opened
    }"
    @mouseenter="handleMouseenter"
    @mouseleave="handleMouseleave"
    @focus="handleMouseenter"
    >
    <div class="v-side-submenu__title" ref="submenu-title"
      @click="handleClick">
      <slot name="title"></slot>
      <i class="v-side-submenu__icon" :class="{'arrow-right': !rootMenu.collapse}"></i>
    </div>
    <template v-if="rootMenu.collapse">
      <transition :name="menuTransitionName">
        <ul class="v-side-menu" v-show="opened" :style="{ backgroundColor: rootMenu.backgroundColor || '' }" role="menu"><slot></slot></ul>
      </transition>
    </template>
    <v-collapse-transition v-else>
      <ul class="v-side-menu" v-show="opened" :style="{ backgroundColor: rootMenu.backgroundColor || '' }" role="menu"><slot></slot></ul>
    </v-collapse-transition>
  </li>
</template>

<script>
  import Emitter from '@/vuego/mixins/emitter';
  import { addClass, removeClass } from '@/vuego/utils/dom';
  import menuMixin from './menu-mixin';

  export default {
    name: 'VSideSubmenu',
    componentName: 'VSideSubmenu',
    mixins: [menuMixin, Emitter],
    components: {
      'v-collapse-transition': {
        functional: true,
        render(createElement, context) {
          const data = {
            on: {
              beforeEnter(el) {
                addClass(el, 'collapse-transition');
                if (!el.dataset) el.dataset = {};

                el.dataset.oldPaddingTop = el.style.paddingTop;
                el.dataset.oldPaddingBottom = el.style.paddingBottom;

                el.style.height = '0';
                el.style.paddingTop = 0;
                el.style.paddingBottom = 0;
              },

              enter(el) {
                el.dataset.oldOverflow = el.style.overflow;
                if (el.scrollHeight !== 0) {
                  el.style.height = `${el.scrollHeight}px`;
                  el.style.paddingTop = el.dataset.oldPaddingTop;
                  el.style.paddingBottom = el.dataset.oldPaddingBottom;
                } else {
                  el.style.height = '';
                  el.style.paddingTop = el.dataset.oldPaddingTop;
                  el.style.paddingBottom = el.dataset.oldPaddingBottom;
                }

                el.style.overflow = 'hidden';
              },

              afterEnter(el) {
                // for safari: remove class then reset height is necessary
                removeClass(el, 'collapse-transition');
                el.style.height = '';
                el.style.overflow = el.dataset.oldOverflow;
              },

              beforeLeave(el) {
                if (!el.dataset) el.dataset = {};
                el.dataset.oldPaddingTop = el.style.paddingTop;
                el.dataset.oldPaddingBottom = el.style.paddingBottom;
                el.dataset.oldOverflow = el.style.overflow;

                el.style.height = `${el.scrollHeight}px`;
                el.style.overflow = 'hidden';
              },

              leave(el) {
                if (el.scrollHeight !== 0) {
                  // for safari: add class after set height, or it will jump to zero height suddenly, weired
                  addClass(el, 'collapse-transition');
                  el.style.height = 0;
                  el.style.paddingTop = 0;
                  el.style.paddingBottom = 0;
                }
              },

              afterLeave(el) {
                removeClass(el, 'collapse-transition');
                el.style.height = '';
                el.style.overflow = el.dataset.oldOverflow;
                el.style.paddingTop = el.dataset.oldPaddingTop;
                el.style.paddingBottom = el.dataset.oldPaddingBottom;
              },
            },
          };
          return createElement('transition', data, context.children);
        },
      },
    },

    props: {
      index: {
        type: String,
        required: true,
      },
    },
    data() {
      return {
        timeout: null,
        items: {},
        submenus: {},
      };
    },
    computed: {
      menuTransitionName() {
        return this.rootMenu.collapse ? 'v-zoom-in-left' : 'v-zoom-in-top';
      },
      opened() {
        return this.rootMenu.openedMenus.indexOf(this.index) > -1;
      },
      active() {
        let isActive = false;
        const submenus = this.submenus;
        const items = this.items;

        Object.keys(items).forEach((index) => {
          if (items[index].active) {
            isActive = true;
          }
        });

        Object.keys(submenus).forEach((index) => {
          if (submenus[index].active) {
            isActive = true;
          }
        });

        return isActive;
      },
      hoverBackground() {
        return this.rootMenu.hoverBackground;
      },
      backgroundColor() {
        return this.rootMenu.backgroundColor || '';
      },
      activeTextColor() {
        return this.rootMenu.activeTextColor || '';
      },
      textColor() {
        return this.rootMenu.textColor || '';
      },
      mode() {
        return this.rootMenu.mode;
      },
    },
    methods: {
      addItem(item) {
        this.$set(this.items, item.index, item);
      },
      removeItem(item) {
        delete this.items[item.index];
      },
      addSubmenu(item) {
        this.$set(this.submenus, item.index, item);
      },
      removeSubmenu(item) {
        delete this.submenus[item.index];
      },
      handleClick() {
        const { rootMenu } = this;
        if (rootMenu.collapse) return;
        this.dispatch('VSideMenu', 'submenu-click', this);
      },
      handleMouseenter() {
        const { rootMenu } = this;
        if (!rootMenu.collapse) return;

        clearTimeout(this.timeout);
        this.timeout = setTimeout(() => {
          this.rootMenu.openMenu(this.index, this.indexPath);
        }, 300);
      },
      handleMouseleave() {
        const { rootMenu } = this;
        if (!rootMenu.collapse) return;

        clearTimeout(this.timeout);
        this.timeout = setTimeout(() => {
          this.rootMenu.closeMenu(this.index);
        }, 300);
      },
    },
    created() {
      this.parentMenu.addSubmenu(this);
      this.rootMenu.addSubmenu(this);
    },
    beforeDestroy() {
      this.parentMenu.removeSubmenu(this);
      this.rootMenu.removeSubmenu(this);
    },
  };
</script>
